home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Fatted Calf
/
The Fatted Calf.iso
/
Modules
/
BackSpaceModules
/
Source
/
WorldSpace
/
WorldSpaceView.m
< prev
Wrap
Text File
|
1994-05-23
|
6KB
|
310 lines
#import <appkit/appkit.h>
#import "WorldSpaceView.h"
#import "SpaceView.h"
#import "Thinker.h"
@implementation WorldSpaceView
// x & y periods in milliseconds
#define X_PERIOD 20000.0
#define Y_PERIOD 19000.0
#define DEFAULT_FPS 20
#define PI 3.1415926535
// #define MAX_IMAGE_WIDTH 200
// #define MAX_IMAGE_HEIGHT 150
#define MAX_IMAGE_WIDTH 256
#define MAX_IMAGE_HEIGHT 256
#define MAX_X_SPEED (26)
#define MAX_Y_SPEED (26)
#define BUFFER_WIDTH (MAX_IMAGE_WIDTH + MAX_X_SPEED + 1)
#define BUFFER_HEIGHT (MAX_IMAGE_HEIGHT + MAX_Y_SPEED + 1)
// move the world to its new position
- oneStep
{
NXRect black = {0,0,0,0};
NXRect ballRect;
BRECT new;
then = now;
now = currentTimeInMs();
// now += 30;
// calculate new ball x & y position
xpos = ((1 + sin(((float)now) / X_PERIOD * 2. * PI))/2.0)
* maxCoord.x;
ypos = ((1 + sin(((float)now) / Y_PERIOD * 2. * PI))/2.0)
* maxCoord.y;
if (xpos < (old.l - MAX_X_SPEED)) xpos = old.l - MAX_X_SPEED;
else if (xpos > (old.l + MAX_X_SPEED)) xpos = old.l + MAX_X_SPEED;
if (ypos < (old.b - MAX_Y_SPEED)) ypos = old.b - MAX_Y_SPEED;
else if (ypos > (old.b + MAX_Y_SPEED)) ypos = old.b + MAX_Y_SPEED;
/* animate by selecting a new image to blit */
[self incrementImageNumber];
new.l = floor(xpos);
new.b = floor(ypos);
new.r = new.l + imageSize.width;
new.t = new.b + imageSize.height;
ballRect.origin.x = 0;
ballRect.origin.y = 0;
ballRect.size.width = imageSize.width;
ballRect.size.height = imageSize.height;
redrawTo.x = MIN(new.l, old.l);
redrawTo.y = MIN(new.b, old.b);
redraw.origin.x = 0;
redraw.origin.y = 0;
redraw.size.width = (MAX(new.r, old.r)) - redrawTo.x + 1;
redraw.size.height = (MAX(new.t, old.t)) - redrawTo.y + 1;
black.size= redraw.size;
[buffer lockFocus];
PSsetgray(0);
NXRectFill(&black);
ballTo.x = new.l - redrawTo.x;
ballTo.y = new.b - redrawTo.y;
[currentImage composite:NX_SOVER fromRect:&ballRect toPoint:&ballTo];
[buffer unlockFocus];
// Now bring it onto the screen
[buffer composite:NX_COPY fromRect:&redraw toPoint:&redrawTo];
old = new;
// now put in the stars...
avoid.origin = redrawTo;
[mySpaceView setVoidRect:&avoid];
[mySpaceView oneStep];
return self;
}
static char *basename(char *path, const char *suffix)
{
char *begin, *end, *name;
int len;
if (strlen(path) < strlen(suffix)) {
end = begin = path;
}
else {
begin = rindex(path, '/');
if (begin) begin++;
else begin = path;
end = path+strlen(path)-strlen(suffix);
if (0 != strcmp(end, suffix))
end = path+strlen(path);
if (end < begin) end = begin;
}
len = end-begin;
name = malloc(len+1);
strncpy(name, begin, len);
name[len] = '\0';
return name;
}
static BOOL noAnimFile = FALSE;
- initFrame:(const NXRect *)frameRect
{
char moduleDirectory[1024];
const char *animSpeed, *animFile, *animName;
char animFrame[1024];
int i, f;
id local_image;
NXRect black = {0, 0, BUFFER_WIDTH, BUFFER_HEIGHT };
[super initFrame:frameRect];
[self allocateGState]; // For faster lock/unlockFocus
[self setClipping:NO]; // even faster...
//in this case, I only need one buffer for several Views
if (!(buffer = [NXImage findImageNamed:"worldBuffer"]))
{
buffer = [[NXImage alloc] initSize:&black.size];
[buffer setName:"worldBuffer"];
}
if ([buffer lockFocus])
{
PSsetgray(0);
NXRectFill(&black);
[buffer unlockFocus];
}
animSpeed = NXGetDefaultValue([NXApp appName], "animSpeed");
if (animSpeed == NULL) framesPerSecond = DEFAULT_FPS;
else framesPerSecond = atoi(animSpeed);
animFile = NXGetDefaultValue([NXApp appName], "animFile");
if (animFile == NULL)
{
sprintf(moduleDirectory,"%s/Globe.anim",
[(BSThinker()) moduleDirectory:"WorldSpace"]);
animFile = moduleDirectory;
}
animName = basename((char *)animFile, ".anim");
imageList = [[List alloc] init];
/* construct the image list */
for (i=0; ; i++)
{
sprintf(animFrame, "%s/%s.%d.tiff", animFile, animName, i+1);
if (!(local_image = [NXImage findImageNamed:animFrame]))
{
if ((f=open(animFrame, O_RDONLY)) < 0) break;
close(f);
local_image = [[NXImage alloc] initFromFile:animFrame];
if (local_image == NULL) break; // never null, even if no file
[local_image setName:animFrame];
}
[imageList addObject:local_image];
if (i == 0) [local_image getSize: &imageSize];
}
numberOfFrames = i;
currentFrame = 0;
if (numberOfFrames == 0)
{
if (!noAnimFile)
NXRunAlertPanel([NXApp appName], "Could not open %s",
NULL, NULL, NULL, animFile);
noAnimFile = TRUE;
return nil;
}
nextRotationTime = 0;
[self newViewSize];
mySpaceView = [[SpaceView alloc] initFrame:frameRect];
avoid.size = imageSize;
return self;
}
- sizeTo:(NXCoord)width :(NXCoord)height
{
[super sizeTo:width :height];
[mySpaceView sizeTo:width :height];
[self newViewSize];
return self;
}
- drawSelf:(const NXRect *)rects :(int)rectCount
{
// if (!rects || !rectCount) return self;
//PSsetgray(0);
//NXRectFill(rects);
//NXRectClip(rects);
return self;
}
- newViewSize
{
//this is called every time View size changes
NXRect black = {0, 0, BUFFER_WIDTH, BUFFER_HEIGHT };
then = now = currentTimeInMs();
if (oldSize.width == bounds.size.width &&
oldSize.height == bounds.size.height)
return self;
else
{
oldSize.width = bounds.size.width;
oldSize.height = bounds.size.height;
}
maxCoord.x = bounds.size.width - imageSize.width;
maxCoord.y = bounds.size.height - imageSize.height;
if (maxCoord.x < 0) maxCoord.x = 0;
if (maxCoord.y < 0) maxCoord.y = 0;
old.l = old.r = maxCoord.x/2;
old.b = old.t = maxCoord.y/2;
ballTo.x = ballTo.y = 0;
if ([buffer lockFocus])
{
PSsetgray(0);
NXRectFill(&black);
[buffer unlockFocus];
}
return self;
}
- incrementImageNumber
{
if (now > nextRotationTime)
{
if (++currentFrame >= numberOfFrames) currentFrame = 0;
currentImage = [imageList objectAt:currentFrame];
nextRotationTime = now + 1000/framesPerSecond;
}
return self;
}
- (const char *)windowTitle
{
return "World in Space";
}
- didLockFocus
{
[mySpaceView didLockFocus];
return self;
}
- inspector:sender
{
char buf[MAXPATHLEN];
if (!sharedInspectorPanel)
{
[NXBundle getPath:buf forResource:"WorldSpace" ofType:"nib" inDirectory:[sender moduleDirectory:"WorldSpace"] withVersion:0];
[NXApp loadNibFile:buf owner:self withNames:NO];
}
return sharedInspectorPanel;
}
@end